package org.softmed.rest.admin.file;

import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class TreeDropTarget implements DropTargetListener {

	DropTarget target;

	JTree targetTree;
	FileManager filemanager;
	FileBrowser fileBrowser;

	public TreeDropTarget(JTree tree, FileBrowser fileBrowser) {
		this.fileBrowser = fileBrowser;
		targetTree = tree;
		target = new DropTarget(targetTree, this);
	}

	/*
	 * Drop Event Handlers
	 */
	private TreeNode getNodeForEvent(DropTargetDragEvent dtde) {
		Point p = dtde.getLocation();
		DropTargetContext dtc = dtde.getDropTargetContext();
		JTree tree = (JTree) dtc.getComponent();
		TreePath path = tree.getClosestPathForLocation(p.x, p.y);
		return (TreeNode) path.getLastPathComponent();
	}

	public void dragEnter(DropTargetDragEvent dtde) {
		TreeNode node = getNodeForEvent(dtde);
		if (node.isLeaf()) {
			dtde.rejectDrag();
		} else {
			// start by supporting move operations
			// dtde.acceptDrag(DnDConstants.ACTION_MOVE);
			dtde.acceptDrag(dtde.getDropAction());
		}
	}

	public void dragOver(DropTargetDragEvent dtde) {
		TreeNode node = getNodeForEvent(dtde);
		if (node.isLeaf()) {
			dtde.rejectDrag();
		} else {
			// start by supporting move operations
			// dtde.acceptDrag(DnDConstants.ACTION_MOVE);
			dtde.acceptDrag(dtde.getDropAction());
		}
	}

	public void dragExit(DropTargetEvent dte) {
	}

	public void dropActionChanged(DropTargetDragEvent dtde) {
	}

	public void drop(DropTargetDropEvent dtde) {
		Point pt = dtde.getLocation();
		DropTargetContext dtc = dtde.getDropTargetContext();
		JTree tree = (JTree) dtc.getComponent();
		TreePath parentpath = tree.getClosestPathForLocation(pt.x, pt.y);
		DefaultMutableTreeNode parentObject = (DefaultMutableTreeNode) parentpath
				.getLastPathComponent();

		CustomFileNode parent = null;
		if (parentObject instanceof CustomFileNode)
			parent = (CustomFileNode) parentObject;

		if (parentObject.isLeaf()) {
			dtde.rejectDrop();
			return;
		}

		try {
			Transferable tr = dtde.getTransferable();
			DataFlavor[] flavors = tr.getTransferDataFlavors();
			for (int i = 0; i < flavors.length; i++) {
				if (tr.isDataFlavorSupported(flavors[i])) {
					dtde.acceptDrop(dtde.getDropAction());
					TreePath p = (TreePath) tr.getTransferData(flavors[i]);
					CustomFileNode node = (CustomFileNode) p
							.getLastPathComponent();
					DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
					model.insertNodeInto(node, parentObject, 0);
					dtde.dropComplete(true);
					try {
						if (parent != null) {
							String nodePath = node.getFullPath();
							String parentPath = parent.getFullPath();
							fileBrowser.getPathsToNames().remove(nodePath);
							filemanager.move(nodePath, parentPath + "/"
									+ node.getName());
							node.setFullPath(parentPath + "/" + node.getName());
							fileBrowser.getPathsToNames().put(
									node.getFullPath(), node);
						} else {
							fileBrowser.getPathsToNames().remove(
									node.getFullPath());
							filemanager.move(node.getFullPath(), "/"
									+ node.getName());
							node.setFullPath("/" + node.getName());
							fileBrowser.getPathsToNames().put(
									node.getFullPath(), node);
						}
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						
					}
					fileBrowser.refresh();
					return;
				}
			}
			dtde.rejectDrop();
			
		} catch (Exception e) {
			e.printStackTrace();
			dtde.rejectDrop();
			fileBrowser.refresh();
		}
	}

	public FileManager getFilemanager() {
		return filemanager;
	}

	public void setFilemanager(FileManager filemanager) {
		this.filemanager = filemanager;
	}
}